package com.foreveross.bsl.push.application.impl;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;
import javax.inject.Named;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.foreveross.bsl.common.utils.mapper.JsonMapper;
import com.foreveross.bsl.push.application.CheckinMgmtService;
import com.foreveross.bsl.push.application.NoTargetDeviceException;
import com.foreveross.bsl.push.application.PushRequestSubmitException;
import com.foreveross.bsl.push.application.PushService;
import com.foreveross.bsl.push.application.vo.MessageParams;
import com.foreveross.bsl.push.domain.entity.PushRequest;
import com.google.common.base.Stopwatch;

@Named("pushService")
public class DefaultPushService implements PushService {

	private final static Logger log = LoggerFactory.getLogger(DefaultPushService.class);

	@Inject
	private PushDispatcher dispatcher;

	@Inject
	private CheckinMgmtService deviceCheckinMgmt;

	private JsonMapper jsonMapper=JsonMapper.nonEmptyMapper();

	@Override
	public String submitMessage(MessageParams msgParam) throws PushRequestSubmitException{
		log.debug("开始受理推送请求...");
		try {
			Assert.notNull(msgParam);
			Assert.notNull(msgParam.getReceiverType());
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.start();
			//验证MessageParams的正确性
			msgParam.validate();
			boolean exists = this.deviceCheckinMgmt.existsTarget(msgParam);
			if(!exists) {
				throw new NoTargetDeviceException(msgParam);
			}
			if(log.isTraceEnabled()){
				log.trace("推送请求JSON:{}", jsonMapper.toJson(msgParam));
			}
			// 构造推送包（Message、PushTarget）
			PushRequest pr = dispatcher.dispatch(msgParam);
			if(log.isDebugEnabled()){
				log.debug("受理推送请求成功，花费:{}ms ,推送请求Id:{}", stopwatch.elapsed(TimeUnit.MILLISECONDS), pr.getId());
			}
			stopwatch.stop();
			return pr.getId();
		}
		catch(Exception e){
			if(e instanceof NoTargetDeviceException){
				throw (NoTargetDeviceException)e;
			}
			else{
				throw new PushRequestSubmitException(e);
			}
		}
	}

}
